from machine import Pin, ADC, SPI
import utime
import st7789
import urandom

# 自定义颜色定义
GRAY = 0x8410  # 灰色
WHITE = 0xFFFF  # 白色
RED = 0xF800    # 红色
BLACK = 0x0000  # 黑色
GREEN = 0x07E0  # 绿色
BLUE = 0x001F   # 蓝色
YELLOW = 0xFFE0 # 黄色
GOLD = 0xFEA0   # 金色（用于金币）
SILVER = 0xC618 # 银色（用于剑）
WALL_COLOR = 0x5555  # 墙壁颜色（深灰色）
STATUS_BG = 0x1111  # 状态栏背景色
HP_BG_COLOR = 0x3300  # 血条背景色（深红色）

# 屏幕区域划分
STATUS_HEIGHT = 70  # 状态栏高度
GAME_AREA_HEIGHT = 240 - STATUS_HEIGHT  # 游戏区域高度

# 游戏网格配置
CELL_SIZE = 16  # 单元格大小
GRID_WIDTH = 12  # 宽度
GRID_HEIGHT = 10  # 高度

# 计算迷宫居中偏移量
TOTAL_GRID_WIDTH = GRID_WIDTH * CELL_SIZE
SCREEN_WIDTH = 240
MAZE_OFFSET_X = (SCREEN_WIDTH - TOTAL_GRID_WIDTH) // 2  # 水平居中偏移

# 迷宫地图定义
maze_map = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
    [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1],
    [1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
    [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
    [1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]

# 方向向量：上、右、下、左
DIRECTIONS = [(-1, 0), (0, 1), (1, 0), (0, -1)]

# 按键初始化
SPEED_BOOST = Pin(0)  # 速度提升键
SPEED_BOOST.init(Pin.IN)
SPEED_BOOST.pull(Pin.PULL_DOWN)

RESTART_BUTTON = Pin(13)  # 重新开始键
RESTART_BUTTON.init(Pin.IN)
RESTART_BUTTON.pull(Pin.PULL_DOWN)

# 按键状态跟踪
speed_boost_prev_state = 0
restart_prev_state = 0

# 摇杆 ADC 初始化
adc_x_pin = Pin(5)    # X 轴
adc_y_pin = Pin(12)   # Y 轴
adc_x = ADC(adc_x_pin)
adc_y = ADC(adc_y_pin)

# 屏幕初始化
spi = SPI(0, baudrate=40000000, polarity=1, phase=0, bits=8, endia=0, sck=Pin(6), mosi=Pin(8))
display = st7789.ST7789(spi, 240, 240, reset=Pin(11,func=Pin.GPIO, dir=Pin.OUT), dc=Pin(7,func=Pin.GPIO, dir=Pin.OUT))
display.init()

# 游戏初始化函数
def init_game():
    global x, y, base_speed, speed_boost, current_hp, max_hp
    global coins_current, coins_total, level, last_level_time
    global monsters, MAX_MONSTERS, base_monster_speed
    global coins, coin_timer, swords, sword_timer
    global has_sword, sword_activation_time, sword_used, game_over, game_start_time
    global last_time, last_level, last_speed, last_coins, last_hp, last_sword
    
    # 玩家初始设置
    box_size = 8  # 玩家大小
    x = MAZE_OFFSET_X + CELL_SIZE + (CELL_SIZE - box_size) // 2
    y = STATUS_HEIGHT + CELL_SIZE + (CELL_SIZE - box_size) // 2  # 加上状态栏高度
    base_speed = 2   # 玩家基础速度
    speed_boost = 0  # 速度提升值
    
    # 玩家HP
    max_hp = 5
    current_hp = max_hp
    
    # 游戏货币系统
    coins_current = 0  # 当前持有的金币
    coins_total = 0    # 局内总共获取的金币
    
    # 关卡等级系统
    level = 1  # 初始等级
    last_level_time = utime.ticks_ms()  # 记录上次等级提升时间
    
    # 怪物属性重置
    monsters = []
    base_monster_speed = 2  # 基础怪物速度
    MAX_MONSTERS = 3  # 初始最大怪物数量
    # 初始化怪物
    for _ in range(MAX_MONSTERS):
        monsters.append(spawn_new_monster())
    
    # 金币和剑重置
    coins = []  # 存储金币道具的列表
    coin_timer = 0  # 金币生成计时器
    swords = []  # 存储剑的列表
    sword_timer = 0  # 剑生成计时器
    
    # 剑的效果状态
    has_sword = False  # 是否持有剑
    sword_activation_time = 0  # 剑激活时间戳
    sword_used = False  # 剑是否已使用
    
    # 游戏状态
    game_over = False
    game_start_time = utime.ticks_ms()  # 游戏开始时间
    
    # 状态栏状态跟踪变量
    last_time = 0
    last_level = 0
    last_speed = 0
    last_coins = 0
    last_hp = 0
    last_sword = ""
    
    # 初始绘制界面
    display.fill(BLACK)
    draw_status_bar(force_redraw=True)  # 首次强制完全绘制
    draw_maze()

# urandom辅助函数
def randint(min_val, max_val):
    return min_val + urandom.getrandbits(16) % (max_val - min_val + 1)

def uniform(min_val, max_val):
    return min_val + (max_val - min_val) * (urandom.getrandbits(16) / 65535)

def choice(seq):
    return seq[randint(0, len(seq) - 1)]

def get_grid_position(screen_x, screen_y):
    """将屏幕坐标转换为网格坐标"""
    grid_x = (screen_x - MAZE_OFFSET_X) // CELL_SIZE
    grid_y = (screen_y - STATUS_HEIGHT) // CELL_SIZE
    return (grid_x, grid_y)

def is_position_valid(screen_x, screen_y, obj_size):
    """检查位置是否有效（不穿墙且在游戏区域内）"""
    if screen_y + obj_size <= STATUS_HEIGHT or screen_y >= 240:
        return False
        
    if (screen_x < MAZE_OFFSET_X or 
        screen_x + obj_size > MAZE_OFFSET_X + TOTAL_GRID_WIDTH):
        return False
        
    start_grid_x = (screen_x - MAZE_OFFSET_X) // CELL_SIZE
    end_grid_x = (screen_x + obj_size - 1 - MAZE_OFFSET_X) // CELL_SIZE
    start_grid_y = (screen_y - STATUS_HEIGHT) // CELL_SIZE
    end_grid_y = (screen_y + obj_size - 1 - STATUS_HEIGHT) // CELL_SIZE
    
    for grid_y in range(start_grid_y, end_grid_y + 1):
        for grid_x in range(start_grid_x, end_grid_x + 1):
            if (grid_x < 0 or grid_x >= len(maze_map[0]) or
                grid_y < 0 or grid_y >= len(maze_map) or
                maze_map[grid_y][grid_x] == 1):
                return False
                
    return True

def is_line_of_sight_clear(x1, y1, x2, y2):
    """检查两点之间是否有视线（直线上没有墙壁）"""
    start_x, start_y = (x1 - MAZE_OFFSET_X) // CELL_SIZE, (y1 - STATUS_HEIGHT) // CELL_SIZE
    end_x, end_y = (x2 - MAZE_OFFSET_X) // CELL_SIZE, (y2 - STATUS_HEIGHT) // CELL_SIZE
    
    dx = abs(end_x - start_x)
    dy = abs(end_y - start_y)
    sx = 1 if end_x > start_x else -1
    sy = 1 if end_y > start_y else -1
    err = dx - dy
    
    while True:
        if maze_map[start_y][start_x] == 1:
            return False
            
        if start_x == end_x and start_y == end_y:
            break
            
        e2 = 2 * err
        if e2 > -dy:
            err -= dy
            start_x += sx
        if e2 < dx:
            err += dx
            start_y += sy
    
    return True

def draw_status_bar(force_redraw=False):
    """绘制状态栏背景和信息，仅更新变化的部分"""
    global last_time, last_level, last_speed, last_coins, last_hp, last_sword
    
    # 计算当前状态栏信息
    elapsed_time = (utime.ticks_ms() - game_start_time) // 1000
    current_speed = base_speed + speed_boost
    
    # 剑状态文本
    if has_sword:
        remaining_time = max(0, (sword_activation_time + sword_duration - utime.ticks_ms()) // 1000)
        sword_text = "SWORD: %ds" % remaining_time
    else:
        sword_text = ""
    
    # 首次绘制或强制重绘时，绘制整个状态栏背景
    if force_redraw:
        display.fill_rect(0, 0, 240, STATUS_HEIGHT, STATUS_BG)
        redraw_all = True
    else:
        redraw_all = False
    
    # 时间显示 - 左上角
    if elapsed_time != last_time or redraw_all:
        display.fill_rect(10, 5, 100, 15, STATUS_BG)
        time_text = "TIME: %ds" % elapsed_time
        display.draw_string(10, 5, time_text, color=WHITE, bg=STATUS_BG, 
                           size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        last_time = elapsed_time
    
    # 等级显示 - 左中部
    if level != last_level or redraw_all:
        display.fill_rect(10, 25, 100, 15, STATUS_BG)
        level_text = "LEVEL: %d" % level
        display.draw_string(10, 25, level_text, color=YELLOW, bg=STATUS_BG, 
                           size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        last_level = level
    
    # 速度显示 - 右上角
    if current_speed != last_speed or redraw_all:
        display.fill_rect(140, 5, 90, 15, STATUS_BG)
        speed_text = "SPD: %d" % current_speed
        display.draw_string(140, 5, speed_text, color=GREEN, bg=STATUS_BG, 
                           size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        last_speed = current_speed
    
    # 金币显示 - 右中部
    if coins_current != last_coins or redraw_all:
        display.fill_rect(210, 25, 30, 15, STATUS_BG)
        display.draw_string(210, 25, "%d" % coins_current, color=GOLD, bg=STATUS_BG, 
                           size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        if redraw_all:
            display.draw_string(140, 25, "COINS:", color=WHITE, bg=STATUS_BG, 
                               size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        last_coins = coins_current
    
    # 血条显示 - 底部，HP文字在左侧且不带冒号
    if current_hp != last_hp or redraw_all:
        # 绘制血条背景
        hp_bar_width = 100
        hp_bar_height = 12
        hp_text_x = 10  # HP文字位置
        hp_text_y = 50
        hp_bar_x = 40  # 血条右移，位于HP文字右侧
        hp_bar_y = 50
        
        # 先清除血条和文字区域
        display.fill_rect(hp_text_x, hp_bar_y, hp_bar_width + 30, hp_bar_height, STATUS_BG)
        
        # 绘制HP文字（不带冒号）
        display.draw_string(hp_text_x, hp_text_y, "HP", color=WHITE, bg=STATUS_BG, 
                           size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        
        # 绘制血条背景
        display.fill_rect(hp_bar_x, hp_bar_y, hp_bar_width, hp_bar_height, HP_BG_COLOR)
        
        # 计算当前血量百分比并绘制血条
        hp_percentage = current_hp / max_hp
        current_hp_width = int(hp_bar_width * hp_percentage)
        # 确保血条不会超出背景范围
        display.fill_rect(hp_bar_x, hp_bar_y, current_hp_width, hp_bar_height, RED)
        
        last_hp = current_hp
    
    # 剑状态显示 - 右下角
    if sword_text != last_sword or redraw_all:
        display.fill_rect(140, 45, 100, 15, STATUS_BG)
        if sword_text:
            display.draw_string(140, 45, sword_text, color=SILVER, bg=STATUS_BG, 
                               size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=1)
        last_sword = sword_text

def draw_maze():
    """绘制迷宫墙壁，添加居中偏移"""
    for grid_y in range(len(maze_map)):
        for grid_x in range(len(maze_map[0])):
            if maze_map[grid_y][grid_x] == 1:
                screen_x = MAZE_OFFSET_X + grid_x * CELL_SIZE
                screen_y = STATUS_HEIGHT + grid_y * CELL_SIZE
                display.fill_rect(
                    screen_x, 
                    screen_y, 
                    CELL_SIZE, 
                    CELL_SIZE, 
                    WALL_COLOR
                )

def spawn_new_monster():
    """生成一个新怪物，速度基于当前等级"""
    while True:
        grid_x = randint(1, len(maze_map[0]) - 2)
        grid_y = randint(1, len(maze_map) - 2)
        
        if maze_map[grid_y][grid_x] == 0:
            mx = MAZE_OFFSET_X + grid_x * CELL_SIZE + (CELL_SIZE - monster_size) // 2
            my = STATUS_HEIGHT + grid_y * CELL_SIZE + (CELL_SIZE - monster_size) // 2
            
            if is_position_valid(mx, my, monster_size) and abs(mx - x) > CELL_SIZE * 3 and abs(my - y) > CELL_SIZE * 3:
                speed_multiplier = 1.0 + (level - 1) * 0.15
                return {
                    "x": mx, 
                    "y": my, 
                    "color": choice(monster_colors),
                    "speed_variation": uniform(0.9, 1.3) * speed_multiplier,
                    "home_x": mx,
                    "home_y": my,
                    "patrol_dir": randint(0, 3),
                    "patrol_steps": 0,
                    "patrol_max_steps": randint(5, 15),
                    "chasing": False,
                    "lose_sight_counter": 0,
                    "last_seen_x": 0,
                    "last_seen_y": 0
                }

def draw_box(x, y, color=RED):
    box_size = 8  # 玩家大小
    display.fill_rect(x, y, box_size, box_size, color)

def draw_monster(mx, my, color=GREEN):
    monster_size = 8  # 怪物大小
    display.fill_rect(mx, my, monster_size, monster_size, color)

def draw_coin(cx, cy):
    coin_size = 5  # 金币大小
    display.fill_rect(cx, cy, coin_size, coin_size, GOLD)

def draw_sword(sx, sy):
    sword_size = 6  # 剑大小
    display.fill_rect(sx, sy, sword_size, sword_size, SILVER)

def show_game_over():
    display.fill_rect(0, 0, 240, 240, 0x0000 | 0x8000)
    display.draw_string(80, 70, "GAME", color=YELLOW, bg=0x0000, 
                       size=4, vertical=False, rotate=st7789.ROTATE_0, spacing=3)
    display.draw_string(80, 110, "OVER", color=YELLOW, bg=0x0000, 
                       size=4, vertical=False, rotate=st7789.ROTATE_0, spacing=3)
    display.draw_string(30, 150, "LEVEL:", color=WHITE, bg=0x0000, 
                       size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=2)
    display.draw_string(130, 150, "%d" % level, color=YELLOW, bg=0x0000, 
                       size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=2)
    display.draw_string(30, 180, "TOTAL COINS:", color=WHITE, bg=0x0000, 
                       size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=2)
    display.draw_string(180, 180, "%d" % coins_total, color=GOLD, bg=0x0000, 
                       size=2, vertical=False, rotate=st7789.ROTATE_0, spacing=2)
    display.draw_string(50, 210, "PRESS E TO RESTART", color=WHITE, bg=0x0000, 
                       size=1, vertical=False, rotate=st7789.ROTATE_0, spacing=1)

def check_collision(rect1, rect2):
    x1, y1, w1, h1 = rect1
    x2, y2, w2, h2 = rect2
    return (x1 < x2 + w2 and
            x1 + w1 > x2 and
            y1 < y2 + h2 and
            y1 + h1 > y2)

def spawn_coin():
    while True:
        grid_x = randint(1, len(maze_map[0]) - 2)
        grid_y = randint(1, len(maze_map) - 2)
        
        if maze_map[grid_y][grid_x] == 0:
            cx = MAZE_OFFSET_X + grid_x * CELL_SIZE + randint(2, CELL_SIZE - coin_size - 2)
            cy = STATUS_HEIGHT + grid_y * CELL_SIZE + randint(2, CELL_SIZE - coin_size - 2)
            
            if is_position_valid(cx, cy, coin_size):
                coin_rect = (cx, cy, coin_size, coin_size)
                overlap = False
                for monster in monsters:
                    monster_rect = (monster["x"], monster["y"], monster_size, monster_size)
                    if check_collision(coin_rect, monster_rect):
                        overlap = True
                        break
                        
                if not overlap:
                    coins.append({"x": cx, "y": cy})
                    break

def spawn_sword():
    while True:
        grid_x = randint(1, len(maze_map[0]) - 2)
        grid_y = randint(1, len(maze_map) - 2)
        
        if maze_map[grid_y][grid_x] == 0:
            sx = MAZE_OFFSET_X + grid_x * CELL_SIZE + randint(2, CELL_SIZE - sword_size - 2)
            sy = STATUS_HEIGHT + grid_y * CELL_SIZE + randint(2, CELL_SIZE - sword_size - 2)
            
            if is_position_valid(sx, sy, sword_size):
                sword_rect = (sx, sy, sword_size, sword_size)
                overlap = False
                for monster in monsters:
                    monster_rect = (monster["x"], monster["y"], monster_size, monster_size)
                    if check_collision(sword_rect, monster_rect):
                        overlap = True
                        break
                for coin in coins:
                    coin_rect = (coin["x"], coin["y"], coin_size, coin_size)
                    if check_collision(sword_rect, coin_rect):
                        overlap = True
                        break
                        
                if not overlap:
                    swords.append({"x": sx, "y": sy})
                    break

def check_level_up():
    """检查是否需要升级关卡，每40秒升级一次，每提升1级增加一个怪物"""
    global level, last_level_time, base_monster_speed, MAX_MONSTERS, monsters
    current_time = utime.ticks_ms()
    
    if utime.ticks_diff(current_time, last_level_time) >= LEVEL_UP_INTERVAL:
        level += 1
        last_level_time = current_time
        
        # 提升现有怪物速度
        for monster in monsters:
            monster["speed_variation"] *= 1.15
        
        # 每提升1级增加一个怪物
        MAX_MONSTERS += 1
        # 生成并添加新怪物
        new_monster = spawn_new_monster()
        if new_monster:  # 确保成功生成新怪物
            monsters.append(new_monster)
                
        return True
    return False

# 游戏常量定义
sword_duration = 5000  # 剑效果持续时间（毫秒）- 5秒
monster_size = 8  # 怪物大小
coin_size = 5  # 金币大小
sword_size = 6  # 剑大小
LEVEL_UP_INTERVAL = 40000  # 等级提升间隔（毫秒）- 40秒
MONSTER_VISION_RANGE = 4  # 怪物视野范围（格子数）
MONSTER_CRUISE_RADIUS = 5  # 怪物巡航半径（格子数）
MONSTER_CHASE_DURATION = 20  # 失去视野后继续追逐的步数
monster_colors = [GREEN, BLUE, YELLOW]  # 不同怪物颜色
max_coins = 3  # 最大金币道具数量
coin_spawn_interval = 80  # 金币生成间隔
max_swords = 1  # 最大剑数量
sword_spawn_interval = 300  # 剑生成间隔

# 初始化游戏
init_game()

# 游戏主循环
while True:
    # 检查重新开始按键
    restart_state = RESTART_BUTTON.value()
    if restart_state == 1 and restart_prev_state == 0:
        init_game()  # 重新初始化游戏
    
    restart_prev_state = restart_state
    
    if game_over:
        show_game_over()
        utime.sleep_ms(1000)
        continue
    
    # 检查关卡升级
    level_updated = check_level_up()
    
    # 检查剑的效果是否过期
    if has_sword and utime.ticks_ms() > sword_activation_time + sword_duration:
        has_sword = False
        sword_used = False
    
    # 读取摇杆值（移动控制）
    x_val = adc_x.read()
    y_val = adc_y.read()
    
    # 读取速度提升按键状态
    speed_boost_state = SPEED_BOOST.value()
    
    # 保存当前位置用于清除
    current_x, current_y = x, y
    
    # 清除玩家旧位置
    draw_box(current_x, current_y, BLACK)
    
    # 清除所有怪物旧位置
    for monster in monsters:
        display.fill_rect(monster["x"], monster["y"], monster_size, monster_size, BLACK)
    
    # 清除所有金币旧位置
    for coin in coins:
        display.fill_rect(coin["x"], coin["y"], coin_size, coin_size, BLACK)
    
    # 清除所有剑旧位置
    for sword in swords:
        display.fill_rect(sword["x"], sword["y"], sword_size, sword_size, BLACK)

    # 玩家移动逻辑
    new_x, new_y = x, y
    current_speed = base_speed + speed_boost
    
    # 摇杆X轴控制左右移动
    if x_val > 1500:
        new_x += current_speed   # 右
    elif x_val < 400:
        new_x -= current_speed   # 左

    # 摇杆Y轴控制上下移动
    if y_val > 1500:
        new_y -= current_speed   # 上
    elif y_val < 400:
        new_y += current_speed   # 下

    # 检查新位置是否有效
    if is_position_valid(new_x, new_y, 8):  # 8是玩家大小
        x, y = new_x, new_y

    # 处理速度提升按键功能
    if speed_boost_state == 1 and speed_boost_prev_state == 0:
        if coins_current >= 10:
            coins_current -= 10
            speed_boost += 1
    
    speed_boost_prev_state = speed_boost_state

    # 怪物视野检测与状态更新
    for monster in monsters:
        dx = abs(x - monster["x"]) // CELL_SIZE
        dy = abs(y - monster["y"]) // CELL_SIZE
        distance = max(dx, dy)
        
        if distance <= MONSTER_VISION_RANGE and is_line_of_sight_clear(monster["x"], monster["y"], x, y):
            monster["chasing"] = True
            monster["lose_sight_counter"] = 0
            monster["last_seen_x"] = x
            monster["last_seen_y"] = y
        else:
            if monster["chasing"]:
                monster["lose_sight_counter"] += 1
                if monster["lose_sight_counter"] >= MONSTER_CHASE_DURATION:
                    monster["chasing"] = False

    # 怪物移动逻辑
    for monster in monsters:
        current_mx, current_my = monster["x"], monster["y"]
        new_mx, new_my = current_mx, current_my
        move_speed = int(base_monster_speed * monster["speed_variation"])
        
        if monster["chasing"]:
            target_x, target_y = monster["last_seen_x"], monster["last_seen_y"]
            
            dx = 0
            dy = 0
            if current_mx < target_x:
                dx = move_speed
            elif current_mx > target_x:
                dx = -move_speed
                
            if current_my < target_y:
                dy = move_speed
            elif current_my > target_y:
                dy = -move_speed
        else:
            monster["patrol_steps"] += 1
            
            if monster["patrol_steps"] >= monster["patrol_max_steps"]:
                monster["patrol_steps"] = 0
                monster["patrol_max_steps"] = randint(5, 15)
                
                if randint(0, 9) < 7:
                    monster["patrol_dir"] = randint(0, 3)
                else:
                    if current_mx < monster["home_x"]:
                        monster["patrol_dir"] = 1  # 右
                    elif current_mx > monster["home_x"]:
                        monster["patrol_dir"] = 3  # 左
                        
                    if current_my < monster["home_y"]:
                        monster["patrol_dir"] = 2  # 下
                    elif current_my > monster["home_y"]:
                        monster["patrol_dir"] = 0  # 上
            
            dx, dy = DIRECTIONS[monster["patrol_dir"]]
            dx *= move_speed
            dy *= move_speed
        
        temp_mx, temp_my = current_mx + dx, current_my + dy
        if is_position_valid(temp_mx, temp_my, monster_size):
            new_mx, new_my = temp_mx, temp_my
        else:
            monster["patrol_dir"] = randint(0, 3)
            dx, dy = DIRECTIONS[monster["patrol_dir"]]
            dx *= move_speed
            dy *= move_speed
            
            if is_position_valid(current_mx + dx, current_my + dy, monster_size):
                new_mx, new_my = current_mx + dx, current_my + dy
        
        monster["x"], monster["y"] = new_mx, new_my

    # 金币生成逻辑
    coin_timer += 1
    if coin_timer >= coin_spawn_interval and len(coins) < max_coins:
        coin_timer = 0
        spawn_coin()
    
    # 剑生成逻辑
    sword_timer += 1
    if sword_timer >= sword_spawn_interval and len(swords) < max_swords and not has_sword:
        sword_timer = 0
        spawn_sword()

    # 碰撞检测与游戏逻辑
    player_rect = (x, y, 8, 8)  # 玩家大小
    
    # 金币碰撞检测
    coins_to_remove = []
    for i, coin in enumerate(coins):
        if check_collision(player_rect, (coin["x"], coin["y"], coin_size, coin_size)):
            coins_to_remove.append(i)
            coins_current += 1
            coins_total += 1
    
    for i in reversed(coins_to_remove):
        del coins[i]
    
    # 剑碰撞检测
    swords_to_remove = []
    for i, sword in enumerate(swords):
        if check_collision(player_rect, (sword["x"], sword["y"], sword_size, sword_size)):
            swords_to_remove.append(i)
            has_sword = True
            sword_activation_time = utime.ticks_ms()
            sword_used = False
            coins_current += 5
            coins_total += 5
    
    for i in reversed(swords_to_remove):
        del swords[i]

    # 怪物碰撞检测
    monsters_to_remove = []
    for i, monster in enumerate(monsters):
        if check_collision(player_rect, (monster["x"], monster["y"], monster_size, monster_size)):
            if has_sword and not sword_used:
                monsters_to_remove.append(i)
                has_sword = False
                sword_used = True
                coins_current += 3
                coins_total += 3
            else:
                current_hp -= 1
                
                while True:
                    grid_x = randint(1, len(maze_map[0]) - 2)
                    grid_y = randint(1, len(maze_map) - 2)
                    if maze_map[grid_y][grid_x] == 0:
                        mx = MAZE_OFFSET_X + grid_x * CELL_SIZE + (CELL_SIZE - monster_size) // 2
                        my = STATUS_HEIGHT + grid_y * CELL_SIZE + (CELL_SIZE - monster_size) // 2
                        if is_position_valid(mx, my, monster_size):
                            monster["x"], monster["y"] = mx, my
                            monster["home_x"], monster["home_y"] = mx, my
                            break
                
                if current_hp <= 0:
                    game_over = True
                    break
    
    for i in reversed(monsters_to_remove):
        del monsters[i]

    # 绘制游戏元素
    draw_box(x, y, RED)
    for monster in monsters:
        draw_monster(monster["x"], monster["y"], monster["color"])
    for coin in coins:
        draw_coin(coin["x"], coin["y"])
    for sword in swords:
        draw_sword(sword["x"], sword["y"])
    
    # 绘制状态栏 - 只更新变化的部分
    draw_status_bar()

    utime.sleep_ms(80)
    